package com.jobsys;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory;
import com.jfinal.plugin.activerecord.IDataSourceProvider;
import com.jfinal.plugin.activerecord.dialect.AnsiSqlDialect;
import com.jfinal.plugin.activerecord.dialect.Dialect;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.dialect.OracleDialect;
import com.jfinal.plugin.activerecord.dialect.PostgreSqlDialect;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.render.ViewType;
import com.jobsys.config.ConfigInit;
import com.jobsys.controller.JobsController;
import com.jobsys.controller.ManagerController;
import com.jobsys.controller.TaskController;
import com.jobsys.controller.UserController;
import com.jobsys.model.MBaseParam;
import com.jobsys.model.MJobinfo;
import com.jobsys.model.MUserinfo;
import com.jobsys.model.Task;
import com.jobsys.quartz.QuartzPlugin;
import com.jobsys.utils.xx;

public class RouteConfig extends JFinalConfig {
	/** EOVA所在数据库的类型 **/
	public static String JOB_DBTYPE = "mysql";
	/** Eova配置属性 **/
	protected static Map<String, String> props = new HashMap<String, String>();
	/** 数据源列表 **/
	protected static List<String> dataSources = new ArrayList<String>();

	public static Map<String, String> getProps() {
		return props;
	}

	public static void setProps(Map<String, String> props) {
		RouteConfig.props = props;
	}

	public static List<String> getDataSources() {
		return dataSources;
	}

	public static void setDataSources(List<String> dataSources) {
		RouteConfig.dataSources = dataSources;
	}

	/*	*//**
			 * Run Server
			 *
			 * @param args
			 *//*
			 * public static void main(String[] args) { JFinal.start("webapp",
			 * 80, "/", 0); }
			 */

	@Override
	public void configConstant(Constants me) {
		// TODO Auto-generated method stub
		me.setDevMode(true);
		me.setEncoding("utf-8");
		me.setViewType(ViewType.JSP);

		// 初始化配置文件
		ConfigInit.initConfig();
	}

	@Override
	public void configRoute(Routes me) {
		// TODO Auto-generated method stub
		// 自定义的路由配置往这里加。。。
		// me.add("/user", UserController.class);

		me.add("/", UserController.class);
		me.add("/user", UserController.class);
		me.add("/job", JobsController.class);
		me.add("/task", TaskController.class);
		me.add("/manager", ManagerController.class);
	}

	@Override
	public void configPlugin(Plugins plugins) {
		// TODO Auto-generated method stub
		System.err.println("Config Plugins Starting...");

		String job_url, job_user, job_pwd;

		job_url = props.get("job_url");
		job_user = props.get("job_user");
		job_pwd = props.get("job_pwd");

		// 默认数据源
		{
			DruidPlugin dp = initDruidPlugin(job_url, job_user, job_pwd);
			ActiveRecordPlugin arp = initActiveRecordPlugin(job_url, xx.DS_JOB, dp);
			System.out.println("load eova datasource:" + job_url + "/" + job_user);

			marketMapping(arp);

			plugins.add(dp).add(arp);

			// 注册数据源
			dataSources.add(xx.DS_JOB);

			try {
				// 数据库类型
				JOB_DBTYPE = JdbcUtils.getDbType(job_url, JdbcUtils.getDriverClassName(job_url));
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		// 自定义插件
		plugin(plugins);

		// 初始化ServiceManager
		// ServiceManager.init();

		// 配置EhCachePlugin插件
		plugins.add(new EhCachePlugin());

		// 配置Quartz
		boolean isQuartz = xx.getConfigBool("isQuartz", true);
		if (isQuartz) {
			QuartzPlugin quartz = new QuartzPlugin();
			plugins.add(quartz);
		}
	}

	@Override
	public void configInterceptor(Interceptors me) {
		// TODO Auto-generated method stub
		// 添加拦截器
		// me.add(new UserAuthorInterceptor()); // 添加用户拦截器
	}

	@Override
	public void configHandler(Handlers me) {
		// TODO Auto-generated method stub

	}

	/**
	 * init Druid
	 * 
	 * @param url
	 *            JDBC
	 * @param username
	 *            数据库用户
	 * @param password
	 *            数据库密码
	 * @return
	 */
	protected DruidPlugin initDruidPlugin(String url, String username, String password) {
		// 设置方言
		WallFilter wall = new WallFilter();
		String dbType = null;
		try {
			dbType = JdbcUtils.getDbType(url, JdbcUtils.getDriverClassName(url));
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		wall.setDbType(dbType);

		DruidPlugin dp = new DruidPlugin(url, username, password);
		dp.addFilter(new StatFilter());
		dp.addFilter(wall);
		return dp;

	}

	/**
	 * init ActiveRecord
	 * 
	 * @param url
	 *            JDBC
	 * @param ds
	 *            DataSource
	 * @param dp
	 *            Druid
	 * @return
	 */
	protected ActiveRecordPlugin initActiveRecordPlugin(String url, String ds, IDataSourceProvider dp) {
		ActiveRecordPlugin arp = new ActiveRecordPlugin(ds, dp);
		// 提升事务级别保证事务回滚
		int lv = xx.toInt(props.get("transaction_level"), java.sql.Connection.TRANSACTION_REPEATABLE_READ);
		arp.setTransactionLevel(lv);

		String dbType;
		try {
			dbType = JdbcUtils.getDbType(url, JdbcUtils.getDriverClassName(url));
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}

		// 统一全部默认小写
		arp.setContainerFactory(new CaseInsensitiveContainerFactory(true));

		Dialect dialect;
		if (JdbcConstants.MYSQL.equalsIgnoreCase(dbType) || JdbcConstants.H2.equalsIgnoreCase(dbType)) {
			dialect = new MysqlDialect();
		} else if (JdbcConstants.ORACLE.equalsIgnoreCase(dbType)) {
			dialect = new OracleDialect();
			((DruidPlugin) dp).setValidationQuery("select 1 FROM DUAL");
		} else if (JdbcConstants.POSTGRESQL.equalsIgnoreCase(dbType)) {
			dialect = new PostgreSqlDialect();
		} else {
			// 默认使用标准SQL方言
			dialect = new AnsiSqlDialect();
		}
		arp.setDialect(dialect);

		// 是否显示SQL
		Boolean isShow = xx.toBoolean(props.get("showSql"), false);
		if (isShow != null) {
			arp.setShowSql(isShow);
		}

		return arp;
	}

	/**
	 * 自定义数据源Model映射
	 *
	 * @param arp
	 */
	protected void marketMapping(ActiveRecordPlugin arp) {
		// 自定义业务Model映射往这里加
		arp.addMapping("baseparam", MBaseParam.class);
		arp.addMapping("taskinfo", Task.class);
		arp.addMapping("jobinfo", MJobinfo.class);
		arp.addMapping("userinfo", MUserinfo.class);
	}

	/**
	 * Custom Plugin
	 * 
	 * @param plugins
	 * @return
	 */
	protected void plugin(Plugins plugins) {
	}
}
